/***
 * @Date: 2020-07-09 16:54:38
 * @LastEditors: leehave
 * @LastEditTime: 2020-09-08 17:24:23
 */
const path = require("path");
const webpack = require("webpack");
const CompressionWebpackPlugin = require("compression-webpack-plugin");
const UglifyjsWebpackPlugin = require("uglifyjs-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");
const version = require("./package.json").version;

const {
  NODE_ENV,
  port,
  npm_config_port,
  VUE_APP_BASE_API,
  VUE_APP_API_URL,
  VUE_APP_WEB_URL,
  ANALYZE,
  VUE_APP_STATIC_PATH
} = process.env;
const IS_DEV = NODE_ENV === "development";
const startPort = port || npm_config_port || 8080;
const defaultSetting = require("./src/setting");
const { cdnUrl, title, outputDir } = defaultSetting;
console.log(VUE_APP_API_URL);

const VUE_STATIC_PATH = "cloud.henankejue.com/staticfile";
function resolve(dir) {
  return path.join(__dirname, dir);
}

function addStyleResource(rule) {
  rule
    .use("style-resource")
    .loader("style-resources-loader")
    .options({
      patterns: [
        resolve("./src/assets/less/theme.less"),
        resolve("./src/assets/less/mixin.less")
      ]
    });
}

const cdnMap = {
  css: [`https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css`],
  js: [
    `https://unpkg.com/vue/dist/vue.min.js`,
    `https://unpkg.com/vue-router/dist/vue-router.min.js`,
    `https://cdn.bootcdn.net/ajax/libs/vuex/3.1.0/vuex.min.js`,
    `https://unpkg.com/axios@0.19.0/dist/axios.min.js`,
    `https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js`
  ]
};

// 那些资源加载cdn
const externals = {
  vue: "Vue",
  "vue-router": "VueRouter",
  vuex: "Vuex",
  axios: "axios",
  vant: "vant"
};

// 别名配置
const alias = {
  "@": resolve("src") // 主目录
};

// 本地服务
const devServer = {
  port: startPort,
  open: true,
  overlay: {
    warnings: false,
    errors: true
  },
  proxy: {
    "/api": {
      target: VUE_APP_API_URL,
      changeOrigin: true
    }
  }
};

// 公共配置
const commonPlugins = [
  new webpack.DefinePlugin({
    __VERSION__: JSON.stringify(version)
  }),
  new webpack.optimize.MinChunkSizePlugin({
    minChunkSize: 30000 // Minimum number of characters
  })
  
];

const commonWebPackConfig = {
  name: title,
  plugins: [...commonPlugins],
  resolve: {
    alias
  }
};

module.exports = {
  // 打包后静态资源地址
  publicPath: IS_DEV ? "/" : cdnUrl,
  // 打包的文件夹名
  outputDir,
  lintOnSave: false,
  assetsDir: "static",
  productionSourceMap: false, // 开启sourceMap 注意发布完成之后要删除掉
  devServer,

  configureWebpack: () => {},

  chainWebpack(config) {
    config.plugins.delete("preload");
    // config.plugins.delete("prefetch");
    // config
    //   .plugin("webpack-bundle-analyzer")
    //   .use(require("webpack-bundle-analyzer").BundleAnalyzerPlugin);
    // 全局注入theme.less
    const types = ["vue-modules", "vue", "normal-modules", "normal"];
    types.forEach(type =>
      addStyleResource(config.module.rule("less").oneOf(type))
    );
    config.resolve.alias
      .set("@", resolve("src"))
      .set("assets", resolve("src/assets"))
      .set("views", resolve("src/views"))
      .set("components", resolve("src/components"));

    // set svg-sprite-loader

    // set preserveWhitespace
    config.module
      .rule("vue")
      .use("vue-loader")
      .loader("vue-loader")
      .tap(options => {
        options.compilerOptions.preserveWhitespace = true;
        return options;
      })
      .end();

    // config
    //   // https://webpack.js.org/configuration/devtool/#development
    //   .when(!IS_DEV, config => config.devtool("cheap-source-map"));

    config.plugin("html").tap(args => {
      args[0].title = title; // 应用的名字
      return args;
    });

    config
      .plugin("ignore")
      .use(
        new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn$/)
      );

    if (!IS_DEV) {
      config.plugin("html").tap(args => {
        args[0].cdn = cdnMap;
        args[0].minify.minifyCSS = true; // 压缩html中的css
        return args;
      });
      config.externals(externals);
      // 开启gzip 但是Nginx上也要做配置
      config
        .plugin("compression")
        .use(CompressionWebpackPlugin)
        .tap(() => [
          {
            test: /\.js$|\.html$|\.css/, // 匹配文件名
            threshold: 10240, // 超过10k进行压缩
            deleteOriginalAssets: false // 是否删除源文件
          }
        ]);
      config.optimization.minimizer = [
        new UglifyjsWebpackPlugin({
          // 生产环境推荐关闭 sourcemap 防止源码泄漏
          // 服务端通过前端发送的行列，根据 sourcemap 转为源文件位置
          sourceMap: false,
          uglifyOptions: {
            warnings: false,
            compress: {
              drop_console: true,
              drop_debugger: true
            }
          }
        })
      ];
      config
        .plugin("ScriptExtHtmlWebpackPlugin")
        .after("html")
        .use(ScriptExtHtmlWebpackPlugin, [
          {
            // `runtime` must same as runtimeChunk name. default is `runtime`
            inline: /runtime\..*\.js$/
          }
        ])
        .end();

      config.optimization.splitChunks({
        chunks: "all",
        maxSize: 100000, // 依赖包超过300000bit将被单独打包
        cacheGroups: {
          common: {
            name: "chunk-common",
            chunks: "initial",
            minChunks: 3,
            // maxInitialRequests: 5,
            // minSize: 0,
            priority: -10,
            reuseExistingChunk: true,
            // enforce: true,
          },
          babellibs: {
            name: "chunk-bebel", // split vantUI into a single package
            priority: 2, // the weight needs to be larger than libs and app or it will be packaged into libs or app
            test: /[\\/]node_modules[\\/]@babel(.*)/, // in order to adapt to cnpm
            minChunks: 5,
            reuseExistingChunk: true,
          },
          vendors: {
            name: "chunk-vendors",
            test: /[\\/]node_modules[\\/]/,
            chunks: "all",
            priority: 5,
            reuseExistingChunk: true,
            // enforce: true,
          },

        }
      });
      
      config.optimization.runtimeChunk('single')
    }
  },

  css: {
    // 是否使用css分离插件 ExtractTextPlugin
    extract: false,
    // requireModuleExtension: false,
    sourceMap: IS_DEV
  }
};
